前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • React专栏

    • React组合式开发实战

      • 前端开发的四个时代
      • 企业管理系统的前世今生
      • 可视化页面搭建工具
      • 实战篇 01:开发前准备
      • 实战篇 02:项目脚手架
      • 实战篇 03:页面布局方案
      • 实战篇 04:权限管理机制
      • 实战篇 05:菜单匹配逻辑
      • 实战篇 06:消息通知设计
      • 实战篇 07:多语言支持
      • 继往开来:可视化页面搭建工具
    • React Hooks与Immutable实战

    • React SSR服务端渲染与同构实践

    • IM聊天系统前端开发实践

    • 微前端开发实战

    • React进阶实践

  • Vue专栏

  • 移动端专栏

  • Node专栏

  • 前端工程化专栏

  • 算法专栏

  • Typescript专栏

  • 其他专栏

完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

一般情况下,当请求一个包含 Service Worker 的页面,并且此 Service Worker 尚未运行,那么浏览器将会等到 Service Worker 启动之后才会发起导航请求(如下图),也由于受各种因素的影响,Service Worker 的启动时间会有不同程度的延迟,这种延迟将直接导致导航请求的延迟,进而增加了页面的整体渲染时间。

上文中我们提到了导航请求,这里我们先简单了解下相关概念,在 Fetch 规范中的定义为:请求实体为 document 的请求。通俗来讲就是当我们在浏览器的地址栏中输入网址,或通过链接等手段从一个页面跳转到另外一个页面时所发送的请求。由于导航请求响应中的 HTML 负责启动所有脚本、样式、图片等资源的请求,因此任何导航请求的延迟都终将导致空白页问题的出现。

正是为了解决因 Service Worker 启动而导致导航请求的延迟问题,Service Worker 提供了导航预加载机制,该机制在 Service Worker 开始启动时,便立刻发起导航请求,这样 Service Worker 启动便能与导航请求并行执行(如下图),从而大大降低了因延迟而导致空白页的几率。

# 使用

导航预加载的使用非常简单,首先在 Service Worker 的 activate 事件中启用该功能:

self.addEventListener('activate', event => {
  event.waitUntil((async () => {
    if (self.registration.navigationPreload) {
      await self.registration.navigationPreload.enable();
    }
  })());
});
@前端进阶之旅: 代码已经复制到剪贴板

然后在 Service Worker 的 fetch 事件中将预加载的导航请求响应返回即可:

self.addEventListener('fetch', event => {
  const { request } = event;
  if (request.method.toLowerCase() === 'get') {
    event.respondWith((async () => {
      //...其他类型请求处理逻辑
      const preloadResponse = await event.preloadResponse;
      if (preloadResponse) {
        return preloadResponse;
      }
    })());
  }
});
@前端进阶之旅: 代码已经复制到剪贴板
  • 需要注意的是:如果开启了导航预加载,那么在 fetch 事件中必须对 event.preloadResponse 进行消费,否则这将导致该请求会被请求两次。
  • 导航预加载请求中会携带请求头 Service-Worker-Navigation-Preload,且默认值为 true,可通过以下方式来修改其默认值:
navigator.serviceWorker.ready.then(registration => {
  return registration.navigationPreload.setHeaderValue(newValue);
});
fe
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • React专栏

    • React组合式开发实战

      • 前端开发的四个时代
      • 企业管理系统的前世今生
      • 可视化页面搭建工具
      • 实战篇 01:开发前准备
      • 实战篇 02:项目脚手架
      • 实战篇 03:页面布局方案
      • 实战篇 04:权限管理机制
      • 实战篇 05:菜单匹配逻辑
      • 实战篇 06:消息通知设计
      • 实战篇 07:多语言支持
      • 继往开来:可视化页面搭建工具
    • React Hooks与Immutable实战

    • React SSR服务端渲染与同构实践

    • IM聊天系统前端开发实践

    • 微前端开发实战

    • React进阶实践

  • Vue专栏

  • 移动端专栏

  • Node专栏

  • 前端工程化专栏

  • 算法专栏

  • Typescript专栏

  • 其他专栏